home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / security / xinetd / xinetd.2.0.6 / parsers.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-22  |  16.8 KB  |  842 lines

  1. /*
  2.  * (c) Copyright 1992 by Panagiotis Tsirigotis
  3.  * All rights reserved.  The file named COPYRIGHT specifies the terms 
  4.  * and conditions for redistribution.
  5.  */
  6.  
  7. static char RCSid[] = "$Id: parsers.c,v 5.2 1992/11/10 08:18:25 panos Exp $" ;
  8.  
  9. #include <sys/file.h>
  10. #include <syslog.h>
  11. #include <string.h>
  12. #include <netdb.h>
  13. #include <pwd.h>
  14. #include <grp.h>
  15.  
  16. #include "pset.h"
  17. #include "misc.h"
  18.  
  19. #include "defs.h"
  20. #include "parse.h"
  21. #include "sconf.h"
  22. #include "config.h"
  23. #include "addr.h"
  24.  
  25. void msg() ;
  26. void parsemsg() ;
  27. void out_of_memory() ;
  28. char **argv_alloc() ;
  29.  
  30. extern struct name_value success_log_options[] ;
  31. extern struct name_value failure_log_options[] ;
  32. extern struct name_value service_types[] ;
  33. extern struct name_value socket_types[] ;
  34. extern struct name_value service_flags[] ;
  35. extern struct name_value syslog_facilities[] ;
  36. extern struct name_value syslog_levels[] ;
  37.  
  38. extern env_h std_env ;
  39.  
  40.  
  41. /*
  42.  * Find the flags corresponding to strings in "values" and apply
  43.  * them to "*maskp" (apply means add or remove depending on "op")
  44.  * "description" describes the type of flags.
  45.  */
  46. PRIVATE status_e parse_value_list( values, maskp, list, op, description )
  47.     pset_h values ;
  48.     mask_t *maskp ;
  49.     struct name_value list[] ;
  50.     enum assign_op op ;
  51.     char *description ;
  52. {
  53.     register unsigned u ;
  54.     register struct name_value *nvp ;
  55.     char *func = "parse_value_list" ;
  56.  
  57.     for ( u = 0 ; u < pset_count( values ) ; u++ )
  58.     {
  59.         char *name = (char *) pset_pointer( values, u ) ;
  60.  
  61.         nvp = nv_find_value( list, name ) ;
  62.         if ( nvp != NULL )
  63.             if ( op == PLUS_EQ )
  64.                 M_SET( *maskp, nvp->value ) ;
  65.             else
  66.                 M_CLEAR( *maskp, nvp->value ) ;
  67.         else
  68.             parsemsg( LOG_WARNING, func, "Bad %s: %s", description, name ) ;
  69.     }
  70.     return( OK ) ;
  71. }
  72.  
  73.  
  74. status_e type_parser( values, scp, op )
  75.     pset_h values ;
  76.     struct service_config *scp ;
  77.     enum assign_op op ;
  78. {
  79.     return( parse_value_list( values,
  80.                         &scp->type, service_types, PLUS_EQ, "service type" ) ) ;
  81. }
  82.  
  83.  
  84. status_e flags_parser( values, scp, op )
  85.     pset_h values ;
  86.     struct service_config *scp ;
  87.     enum assign_op op ;
  88. {
  89.     return( parse_value_list( values,
  90.                         &scp->flags, service_flags, PLUS_EQ, "service flag" ) ) ;
  91. }
  92.  
  93.  
  94. status_e socket_type_parser( values, scp, op )
  95.     pset_h values ;
  96.     struct service_config *scp ;
  97.     enum assign_op op ;
  98. {
  99.     register struct name_value *nvp ;
  100.     register char *type = (char *) pset_pointer( values, 0 ) ;
  101.     char *func = "socket_type_parser" ;
  102.  
  103.     nvp = nv_find_value( socket_types, type ) ;
  104.     if ( nvp != NULL )
  105.     {
  106.         scp->socket_type = nvp->value ;
  107.         return( OK ) ;
  108.     }
  109.     else
  110.     {
  111.         parsemsg( LOG_ERR, func, "Bad socket type: %s", type ) ;
  112.         return( FAILED ) ;
  113.     }
  114. }
  115.  
  116.  
  117. status_e rpc_version_parser( values, scp, op )
  118.     pset_h values ;
  119.     struct service_config *scp ;
  120.     enum assign_op op ;
  121. {
  122.     struct rpc_data *rdp = RPCDATA( scp ) ;
  123.     char *version = (char *) pset_pointer( values, 0 ) ;
  124.     char *p = strchr( version, '-' ) ;
  125.     char *func = "rpc_version_parser" ;
  126.  
  127.     if ( p == NULL )
  128.         rdp->min_version = rdp->max_version = atoi( version ) ;
  129.     else
  130.     {
  131.         *p = NUL ;
  132.         rdp->min_version = atoi( version ) ;
  133.         rdp->max_version = atoi( p+1 ) ;
  134.         if ( rdp->min_version > rdp->max_version )
  135.         {
  136.             parsemsg( LOG_ERR, func, "bad version range: %s", version ) ;
  137.             return( FAILED ) ;
  138.         }
  139.     }
  140.     return( OK ) ;
  141. }
  142.  
  143.  
  144. status_e protocol_parser( values, scp, op )
  145.     pset_h values ;
  146.     struct service_config *scp ;
  147.     enum assign_op op ;
  148. {
  149.     char *proto_name = (char *) pset_pointer( values, 0 ) ;
  150.     struct protoent *pep ;
  151.     char *func = "protocol_parser" ;
  152.  
  153.     if ( ( pep = getprotobyname( proto_name ) ) == NULL )
  154.     {
  155.         parsemsg( LOG_ERR, func, 
  156.                     "Protocol %s not in /etc/protocols", proto_name ) ;
  157.         return( FAILED ) ;
  158.     }
  159.  
  160.     scp->protocol.name = make_string( 1, proto_name ) ;
  161.     if ( scp->protocol.name == NULL )
  162.     {
  163.         out_of_memory( func ) ;
  164.         return( FAILED ) ;
  165.     }
  166.     scp->protocol.value = pep->p_proto ;
  167.     return( OK ) ;
  168. }
  169.  
  170.  
  171. status_e wait_parser( values, scp, op )
  172.     pset_h values ;
  173.     struct service_config *scp ;
  174.     enum assign_op op ;
  175. {
  176.     char *val = (char *) pset_pointer( values, 0 ) ;
  177.     char *func = "wait_parser" ;
  178.  
  179.     if ( EQ( val, "yes" ) )
  180.         scp->wait = YES ;
  181.     else if ( EQ( val, "no" ) )
  182.         scp->wait = NO ;
  183.     else
  184.         parsemsg( LOG_ERR, func, "Bad value for wait: %s", val ) ;
  185.     return( OK ) ;
  186. }
  187.  
  188.  
  189. status_e user_parser( values, scp, op )
  190.     pset_h values ;
  191.     struct service_config *scp ;
  192.     enum assign_op op ;
  193. {
  194.     char *user = (char *) pset_pointer( values, 0 ) ;
  195.     struct passwd *pw ;
  196.     char *func = "user_parser" ;
  197.  
  198.     pw = getpwnam( user ) ;
  199.     if ( pw == NULL )
  200.     {
  201.         parsemsg( LOG_ERR, func, "Unknown user: %s", user ) ;
  202.         return( FAILED ) ;
  203.     }
  204.     
  205.     scp->uid = pw->pw_uid ;
  206.     scp->user_gid = pw->pw_gid ;
  207.     return( OK ) ;
  208. }
  209.  
  210.  
  211.  
  212. status_e group_parser( values, scp, op )
  213.     pset_h values ;
  214.     struct service_config *scp ;
  215.     enum assign_op op ;
  216. {
  217.     char *group = (char *) pset_pointer( values, 0 ) ;
  218.     struct group *grp ;
  219.     char *func = "group_parser" ;
  220.  
  221.     grp = getgrnam( group ) ;
  222.     if ( grp == NULL )
  223.     {
  224.         parsemsg( LOG_ERR, func, "Unknown group: %s", group ) ;
  225.         return( FAILED ) ;
  226.     }
  227.     
  228.     scp->gid = grp->gr_gid ;
  229.     return( OK ) ;
  230. }
  231.  
  232.  
  233.  
  234. status_e server_parser( values, scp, op )
  235.     pset_h values ;
  236.     struct service_config *scp ;
  237.     enum assign_op op ;
  238. {
  239.     char *server = (char *) pset_pointer( values, 0 ) ;
  240.     char *func = "server_parser" ;
  241.  
  242.     if ( access( server, X_OK ) == -1 )
  243.     {
  244.         parsemsg( LOG_ERR, func, "Server %s is not executable", server ) ;
  245.         return( FAILED ) ;
  246.     }
  247.  
  248.     scp->server = make_string( 1, server ) ;
  249.     if ( scp->server == NULL )
  250.     {
  251.         out_of_memory( func ) ;
  252.         return( FAILED ) ;
  253.     }
  254.     return( OK ) ;
  255. }
  256.  
  257.  
  258.  
  259. status_e server_args_parser( values, scp, op )
  260.     pset_h values ;
  261.     struct service_config *scp ;
  262.     enum assign_op op ;
  263. {
  264.     register char **argv ;
  265.     register unsigned u ;
  266.     unsigned i ;
  267.     register unsigned argv_index ;
  268.     register unsigned n_args = pset_count( values ) ;
  269.     char *func = "server_args_parser" ;
  270.  
  271.     /*
  272.      * Create the argv for a future exec call
  273.      * Reserve space for the server. We cannot use scp->server
  274.      * since it may not have a value yet.
  275.      */
  276.     argv = argv_alloc( n_args+1 ) ;
  277.     
  278.     for ( u = 0, argv_index = 1 ; u < pset_count( values ) ; u++, argv_index++ )
  279.     {
  280.         register char *s = make_string( 1, (char *) pset_pointer( values, u ) ) ;
  281.  
  282.         if ( s == NULL )
  283.         {
  284.             for ( i = 1 ; i < argv_index ; i++ )
  285.                 free( argv[ i ] ) ;
  286.             free( (char *) argv ) ;
  287.             out_of_memory( func ) ;
  288.             return( FAILED ) ;
  289.         }
  290.         argv[ argv_index ] = s ;
  291.     }
  292.  
  293.     argv[ argv_index ] = argv[ 0 ] = NULL ;
  294.     scp->server_argv = argv ;
  295.     return( OK ) ;
  296. }
  297.  
  298.  
  299. status_e instances_parser( values, scp, op )
  300.     pset_h values ;
  301.     struct service_config *scp ;
  302.     enum assign_op op ;
  303. {
  304.     char *instances = (char *) pset_pointer( values, 0 ) ;
  305.     char *func = "instances_parser" ;
  306.  
  307.     if ( EQ( instances, "UNLIMITED" ) )
  308.         scp->instances = UNLIMITED ;
  309.     else
  310.     {
  311.         scp->instances = atoi( instances ) ;
  312.         if ( scp->instances < 0 )
  313.         {
  314.             parsemsg( LOG_ERR, func,
  315.                 "Number of instances is negative: %s", instances ) ;
  316.             return( FAILED ) ;
  317.         }
  318.     }
  319.     return( OK ) ;
  320. }
  321.  
  322.  
  323. status_e id_parser( values, scp, op )
  324.     pset_h values ;
  325.     struct service_config *scp ;
  326.     enum assign_op op ;
  327. {
  328.     char *func = "id_parser" ;
  329.  
  330.     scp->id = make_string( 1, (char *) pset_pointer( values, 0 ) ) ;
  331.     if ( scp->id != NULL )
  332.         return( OK ) ;
  333.     out_of_memory( func ) ;
  334.     return( FAILED ) ;
  335. }
  336.  
  337.  
  338.  
  339. #define PORT_BITS                16
  340. #define PORT_MAX                ( 1 << PORT_BITS )
  341.  
  342. status_e port_parser( values, scp, op )
  343.     pset_h values ;
  344.     struct service_config *scp ;
  345.     enum assign_op op ;
  346. {
  347.     unsigned port = atoi( (char *) pset_pointer( values, 0 ) ) ;
  348.     char *func = "port_parser" ;
  349.  
  350.     if ( port >= PORT_MAX )
  351.     {
  352.         parsemsg( LOG_ERR, func, "port number exceeds %d", PORT_MAX-1 ) ;
  353.         return( FAILED ) ;
  354.     }
  355.     scp->port = port ;
  356.     return( OK ) ;
  357. }
  358.  
  359.  
  360. status_e env_parser( values, scp, op )
  361.     pset_h values ;
  362.     struct service_config *scp ;
  363.     enum assign_op op ;
  364. {
  365.     unsigned u ;
  366.     char *func = "env_parser" ;
  367.  
  368.     if ( op == MINUS_EQ )
  369.     {
  370.         parsemsg( LOG_WARNING, func,
  371.             "operator '-=' not supported for env atribute" ) ;
  372.         return( FAILED ) ;
  373.     }
  374.  
  375.     if ( scp->env == NULL && ( scp->env = pset_create( 5, 5 ) ) == NULL )
  376.     {
  377.         out_of_memory( func ) ;
  378.         return( FAILED ) ;
  379.     }
  380.  
  381.     if ( op == SET_EQ && pset_count( scp->env ) > 0 )
  382.     {
  383.         pset_freeall( scp->env ) ;
  384.         pset_clear( scp->env ) ;
  385.     }
  386.  
  387.     for ( u = 0 ; u < pset_count( values ) ; u++ )
  388.     {
  389.         char *str = (char *) pset_pointer( values, u ) ;
  390.         char *s ;
  391.  
  392.         /*
  393.          * Check if the string contains an '='
  394.          */
  395.         if ( strchr( str, '=' ) == NULL )
  396.         {
  397.             parsemsg( LOG_ERR, func, "%s has no '='", str ) ;
  398.             continue ;
  399.         }
  400.  
  401.         if ( ( s = make_string( 1, str ) ) == NULL )
  402.         {
  403.             out_of_memory( func ) ;
  404.             break ;
  405.         }
  406.         if ( pset_add( scp->env, s ) == NULL )
  407.         {
  408.             out_of_memory( func ) ;
  409.             break ;
  410.         }
  411.     }
  412.     return( OK ) ;
  413. }
  414.  
  415.  
  416. status_e passenv_parser( values, scp, op )
  417.     pset_h values ;
  418.     struct service_config *scp ;
  419.     enum assign_op op ;
  420. {
  421.     pset_h var_set ;
  422.     unsigned u ;
  423.     char *func = "passenv_parser" ;
  424.  
  425.     if ( scp->passenv == NULL &&
  426.                     ( scp->passenv = pset_create( 0, 0 ) ) == NULL )
  427.     {
  428.         out_of_memory( func ) ;
  429.         return( FAILED ) ;
  430.     }
  431.  
  432.     var_set = scp->passenv ;
  433.  
  434.     if ( op == SET_EQ )
  435.     {
  436.         pset_freeall( var_set ) ;
  437.         pset_clear( var_set ) ;
  438.         op = PLUS_EQ ;
  439.     }
  440.  
  441.     for ( u = 0 ; u < pset_count( values ) ; u++ )
  442.     {
  443.         char *env_var = (char *) pset_pointer( values, u ) ;
  444.         unsigned v ;
  445.         boolean_e found ;
  446.  
  447.         /*
  448.          * Check if it is already there
  449.          */
  450.         for ( found = NO, v = 0 ; v < pset_count( var_set ) ; v++ )
  451.             if ( EQ( env_var, (char *) pset_pointer( var_set, v ) ) )
  452.             {
  453.                 found = YES ;
  454.                 break ;
  455.             }
  456.         
  457.         if ( op == MINUS_EQ && found == NO || op != MINUS_EQ && found == YES )
  458.             continue ;
  459.         
  460.         if ( op == MINUS_EQ )
  461.         {
  462.             free( (char *) pset_pointer( var_set, v ) ) ;
  463.             pset_remove_index( var_set, v ) ;
  464.         }
  465.         else
  466.         {
  467.             char *p ;
  468.  
  469.             if ( env_lookup( std_env, env_var ) == CHAR_NULL )
  470.             {
  471.                 parsemsg( LOG_WARNING, func,
  472.                     "undefined environment variable: %s", env_var ) ;
  473.                 continue ;
  474.             }
  475.  
  476.             p = make_string( 1, env_var ) ;
  477.             if ( p == NULL )
  478.             {
  479.                 out_of_memory( func ) ;
  480.                 return( FAILED ) ;
  481.             }
  482.  
  483.             if ( pset_add( var_set, p ) == NULL )
  484.             {
  485.                 free( p ) ;
  486.                 out_of_memory( func ) ;
  487.                 return( FAILED ) ;
  488.             }
  489.         }
  490.     }
  491.     return( OK ) ;
  492. }
  493.  
  494.  
  495.  
  496. status_e disabled_parser( values, scp, op )
  497.     pset_h values ;
  498.     struct service_config *scp ;
  499.     enum assign_op op ;
  500. {
  501.     register unsigned u ;
  502.     char *func = "disabled_parser" ;
  503.  
  504.     if ( scp->disabled == NULL &&
  505.             ( scp->disabled = pset_create( pset_count( values ), 0 ) ) == NULL )
  506.     {
  507.         out_of_memory( func ) ;
  508.         return( FAILED ) ;
  509.     }
  510.     
  511.     for ( u = 0 ; u < pset_count( values ) ; u++ )
  512.     {
  513.         char *name ;
  514.  
  515.         name = make_string( 1, (char *) pset_pointer( values, u ) ) ;
  516.         if ( name == NULL )
  517.         {
  518.             out_of_memory( func ) ;
  519.             break ;                /* ignore the rest */
  520.         }
  521.         
  522.         if ( pset_add( scp->disabled, name ) == NULL )
  523.         {
  524.             free( name ) ;
  525.             parsemsg( LOG_CRIT, func, "out of memory" ) ;
  526.             break ;                /* ignore the rest */
  527.         }
  528.     }
  529.     return( OK ) ;
  530. }
  531.  
  532.  
  533. /*
  534.  * Interpret a number of the form: <num>[m|M|k|K]
  535.  * m and M mean megabytes, k and K mean kilobytes, nothing means bytes
  536.  */
  537. PRIVATE unsigned get_limit( limitstr )
  538.     char *limitstr ;
  539. {
  540.     int multiplier ;
  541.  
  542.     switch ( limitstr[ strlen( limitstr ) - 1 ] )
  543.     {
  544.         case 'k':
  545.         case 'K':
  546.             multiplier = 1024 ;
  547.             break ;
  548.         
  549.         case 'm':
  550.         case 'M':
  551.             multiplier = 1024 * 1024 ;
  552.             break ;
  553.         
  554.         default:
  555.             multiplier = 1 ;
  556.     }
  557.     return( (unsigned) atoi( limitstr ) * multiplier ) ;
  558. }
  559.  
  560.  
  561. PRIVATE status_e parse_filelog( flp, values )
  562.     struct filelog *flp ;
  563.     pset_h values ;
  564. {
  565.     unsigned soft_limit ;
  566.     unsigned hard_limit ;
  567.     char *file ;
  568.     unsigned count = pset_count( values ) ;
  569.     char *func = "parse_filelog" ;
  570.  
  571.     if ( count < 2 || count > 4 )
  572.     {
  573.         parsemsg( LOG_ERR, func, "wrong number of arguments" ) ;
  574.         return( FAILED ) ;
  575.     }
  576.  
  577.     file = make_string( 1, (char *) pset_pointer( values, 1 ) ) ;
  578.     if ( file == NULL )
  579.     {
  580.         out_of_memory( func ) ;
  581.         return( FAILED ) ;
  582.     }
  583.  
  584.     /*
  585.      * Get the limits, if any
  586.      */
  587.     if ( count > 2 )
  588.     {
  589.         soft_limit = get_limit( (char *) pset_pointer( values, 2 ) ) ;
  590.         if ( soft_limit == 0 )
  591.         {
  592.             parsemsg( LOG_ERR, func, "soft limit is 0" ) ;
  593.             free( file ) ;
  594.             return( FAILED ) ;
  595.         }
  596.  
  597.         /*
  598.          * If a hard limit was specified check that it is at least equal 
  599.          * to the soft limit. If no hard limit was specified, determine
  600.          * it from the formula:
  601.          *        hard = soft + x
  602.          * where 
  603.          *        min( 1%soft,LOG_EXTRA_MIN ) <= x <= max( 1%soft,LOG_EXTRA_MAX )
  604.          */
  605.         if ( count == 4 )
  606.         {
  607.             hard_limit = get_limit( (char *) pset_pointer( values, 3 ) ) ;
  608.             if ( hard_limit < soft_limit )
  609.             {
  610.                 parsemsg( LOG_ERR, func,
  611.                     "hard limit (%d) is less than soft limit (%d)",
  612.                             hard_limit, soft_limit ) ;
  613.                 free( file ) ;
  614.                 return( FAILED ) ;
  615.             }
  616.         }
  617.         else
  618.         {
  619.             unsigned extra = soft_limit / 100 ;        /* 1% of soft limit */
  620.  
  621.             if ( extra < LOG_EXTRA_MIN )
  622.                 extra = LOG_EXTRA_MIN ;
  623.             else if ( extra > LOG_EXTRA_MAX )
  624.                 extra = LOG_EXTRA_MAX ;
  625.             hard_limit = soft_limit + extra ;
  626.         }
  627.         flp->soft_limit = soft_limit ;
  628.         flp->hard_limit = hard_limit ;
  629.     }
  630.     flp->filename = file ;
  631.     return( OK ) ;
  632. }
  633.  
  634.  
  635. PRIVATE status_e parse_syslog( slp, values )
  636.     struct syslog *slp ;
  637.     pset_h values ;
  638. {
  639.     char *facility ;
  640.     char *level ;
  641.     struct name_value *nvp ;
  642.     unsigned count = pset_count( values ) ;
  643.     char *func = "parse_syslog" ;
  644.  
  645.     if ( count < 2 || count > 3 )
  646.     {
  647.         parsemsg( LOG_ERR, func, "wrong number of arguments" ) ;
  648.         return( FAILED ) ;
  649.     }
  650.  
  651.     facility = (char *) pset_pointer( values, 1 ) ;
  652.     if ( ( nvp = nv_find_value( syslog_facilities, facility ) ) == NULL )
  653.     {
  654.         parsemsg( LOG_ERR, func, "Unknown syslog facility: %s", facility ) ;
  655.         return( FAILED ) ;
  656.     }
  657.     slp->facility = nvp->value ;
  658.  
  659.     if ( count == 3 )
  660.     {
  661.         level = (char *) pset_pointer( values, 2 ) ;
  662.         if ( ( nvp = nv_find_value( syslog_levels, level ) ) == NULL )
  663.         {
  664.             parsemsg( LOG_ERR, func, "Unknown syslog level: %s", level ) ;
  665.             return( FAILED ) ;
  666.         }
  667.         slp->level = nvp->value ;
  668.     }
  669.     else
  670.         slp->level = DEFAULT_SERVICE_SYSLOG_LEVEL ;
  671.  
  672.     return( OK ) ;
  673. }
  674.  
  675.  
  676. status_e log_type_parser( values, scp, op )
  677.     pset_h values ;
  678.     struct service_config *scp ;
  679.     enum assign_op op ;
  680. {
  681.     struct log *lp = LOG( scp ) ;
  682.     char *type ;
  683.     char *func = "parse_log_type" ;
  684.  
  685.     type = (char *) pset_pointer( values, 0 ) ;
  686.  
  687.     if ( EQ( type, "FILE" ) )
  688.     {
  689.         if ( parse_filelog( FILELOG( lp ), values ) == FAILED )
  690.             return( FAILED ) ;
  691.         lp->log_type = L_FILE ;
  692.     }
  693.     else if ( EQ( type, "SYSLOG" ) )
  694.     {
  695.         if ( parse_syslog( SYSLOG( lp ), values ) == FAILED )
  696.             return( FAILED ) ;
  697.         lp->log_type = L_SYSLOG ;
  698.     }
  699.     else
  700.     {
  701.         parsemsg( LOG_ERR, func, "Unknown log type: %s", type ) ;
  702.         return( FAILED ) ;
  703.     }
  704.     return( OK ) ;
  705. }
  706.  
  707.  
  708.  
  709. PRIVATE status_e parse_log_flags( values, op, maskp, options, name )
  710.     pset_h values ;
  711.     enum assign_op op ;
  712.     mask_t *maskp ;
  713.     struct name_value options[] ;
  714.     char *name ;
  715. {
  716.     if ( op == SET_EQ )
  717.     {
  718.         M_CLEAR_ALL( *maskp ) ;
  719.         op = PLUS_EQ ;
  720.     }
  721.  
  722.     return( parse_value_list( values, maskp, options, op, name ) ) ;
  723. }
  724.  
  725.  
  726. status_e log_on_success_parser( values, scp, op )
  727.     pset_h values ;
  728.     struct service_config *scp ;
  729.     enum assign_op op ;
  730. {
  731.     return( parse_log_flags( values, op,
  732.         &scp->log_on_success, success_log_options, "log-on-success flag" ) ) ;
  733. }
  734.  
  735.  
  736. status_e log_on_failure_parser( values, scp, op )
  737.     pset_h values ;
  738.     struct service_config *scp ;
  739.     enum assign_op op ;
  740. {
  741.     return( parse_log_flags( values, op,
  742.         &scp->log_on_failure, failure_log_options, "log-on_failure flag" ) ) ;
  743. }
  744.  
  745.  
  746.  
  747. PRIVATE status_e parse_inet_addresses( values, op, addr_list )
  748.     pset_h values ;
  749.     enum assign_op op ;
  750.     pset_h *addr_list ;
  751. {
  752.     register unsigned u ;
  753.     pset_h addr_set ;
  754.     status_e (*addrlist_func)() ;
  755.     char *func = "parse_inet_addresses" ;
  756.     
  757.     /*
  758.      * If there are no addresses allocated yet, allocate some
  759.      */
  760.     if ( *addr_list == NULL )
  761.     {
  762.         *addr_list = pset_create( 0, 0 ) ;
  763.         if ( *addr_list == NULL )
  764.         {
  765.             out_of_memory( func ) ;
  766.             return( FAILED ) ;
  767.         }
  768.     }
  769.     addr_set = *addr_list ;
  770.  
  771.     /*
  772.      * If the op was '=' clear the existing list of addresses
  773.      */
  774.     if ( op == SET_EQ )
  775.     {
  776.         op = PLUS_EQ ;
  777.         addrlist_free( addr_set ) ;
  778.         pset_clear( addr_set ) ;
  779.     }
  780.  
  781.     addrlist_func = ( op == PLUS_EQ ) ? addrlist_add : addrlist_remove ;
  782.  
  783.     for ( u = 0 ; u < pset_count( values ) ; u++ )
  784.     {
  785.         register char *str_addr = (char *) pset_pointer( values, u ) ;
  786.  
  787.         if ( (*addrlist_func)( addr_set, str_addr ) == FAILED )
  788.             break ;
  789.     }
  790.     return( OK ) ;
  791. }
  792.  
  793.  
  794.  
  795. status_e only_from_parser( values, scp, op )
  796.     pset_h values ;
  797.     struct service_config *scp ;
  798.     enum assign_op op ;
  799. {
  800.     return( parse_inet_addresses( values, op, &scp->only_from ) ) ;
  801. }
  802.  
  803.  
  804. status_e no_access_parser( values, scp, op )
  805.     pset_h values ;
  806.     struct service_config *scp ;
  807.     enum assign_op op ;
  808. {
  809.     return( parse_inet_addresses( values, op, &scp->no_access ) ) ;
  810. }
  811.  
  812.  
  813. status_e access_times_parser( values, scp, op )
  814.     pset_h values ;
  815.     struct service_config *scp ;
  816.     enum assign_op op ;
  817. {
  818.     register unsigned u ;
  819.     char *func = "access_times_parser" ;
  820.     status_e add_interval() ;
  821.  
  822.     if ( scp->access_times == NULL )
  823.     {
  824.         scp->access_times = pset_create( 0, 0 ) ;
  825.         if ( scp->access_times == NULL )
  826.         {
  827.             out_of_memory( func ) ;
  828.             return( FAILED ) ;
  829.         }
  830.     }
  831.  
  832.     for ( u = 0 ; u < pset_count( values ) ; u++ )
  833.     {
  834.         register char *interval = (char *) pset_pointer( values, u ) ;
  835.  
  836.         if ( add_interval( scp->access_times, interval ) == FAILED )
  837.             break ;
  838.     }
  839.     return( OK ) ;
  840. }
  841.  
  842.